home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 167_01 / bu.c < prev    next >
Text File  |  1985-08-19  |  30KB  |  984 lines

  1. /* BU.C - A File Backup Utility for CP/M-80 & CP/M-86
  2.  *
  3.  * Copyright:    Ian Ashdown
  4.  *        byHeart Software
  5.  *        2 - 2016 West First Avenue
  6.  *        Vancouver, B.C. V6J 1G8
  7.  *        Canada
  8.  *
  9.  * Acknowledgment: DeSmet C code and suggestions for program
  10.  *            improvement courtesy of Dr. Dobb's Journal
  11.  *           Contributing Editor Anthony Skjellum
  12.  *            
  13.  * Version:    1.2    Written for Aztec CII v1.06b (CP/M-80)
  14.  *            and DeSmet C88 v2.2 (CP/M-86)
  15.  *
  16.  * Date:    December 31st, 1983 (Version 1.0)
  17.  *        September 7th, 1984 (Version 1.1)
  18.  *        November 7th, 1985 (Version 1.2)
  19.  *
  20.  * Version Modifications:
  21.  *
  22.  * 24/09/84 - "read()" and "write()" accept maximum of 32767
  23.  *          bytes, not 32768. Functions "copy_file()" and
  24.  *          "verify_file()" modified accordingly.
  25.  * 07/11/85 - function "copy_file()" incorrectly copied file
  26.  *          when last invocation of "read()" exactly filled
  27.  *          input file buffer or input file was of zero length.
  28.  *          Statement added to break copy loop on "read()"
  29.  *          returning zero.
  30.  *
  31.  * BU utilizes the undocumented "archive" file attribute feature
  32.  * of CP/M-80 Versions 2.x and CP/M-86 to automatically detect
  33.  * files that have been changed since the disk was last "backed
  34.  * up" and copy them (with verification) to a backup disk. This
  35.  * program performs the same action as the "A" option of PIP 
  36.  * under Digital Research's MP/M 2, for which the Archive
  37.  * attribute is documented.
  38.  *
  39.  * Usage: BU x[:afn] y [-AFHQSn]
  40.  *
  41.  *      where x = drive name of disk to be backed up
  42.  *        y = drive name of backup disk
  43.  *
  44.  *      and the optional arguments are:
  45.  *
  46.  *        -A      All files, regardless of status
  47.  *        -F      Fast copy (without verification)
  48.  *        -H      Hard disk (files may be split)
  49.  *        -Q        Query each file before backup
  50.  *        -S      System attribute copied to backup
  51.  *        -n      Backup USER 'n' files only (0-31)
  52.  *        afn      Any legal CP/M ambiguous fileref
  53.  *              (can only be used with -n option)
  54.  */
  55.  
  56. #include "stdio.h"
  57. #include "ctype.h"    /* Contains macro for "isdigit()" */
  58.  
  59. /*** DEFINITIONS ***/
  60.  
  61. #define AZTEC    1    /* Aztec CII v1.06b (CP/M-80) */
  62. #define DESMET    0    /* DeSmet C88 v2.2 (CP/M-86) */
  63.  
  64. #if DESMET
  65. #define movmem(src,dest,len)    _mov(len,src,dest)
  66. #endif
  67.  
  68. #define ERROR       -1
  69. #define DEL       -1    /* Deleted fileref flag */
  70. #define ALL       -1    /* All user numbers flag */
  71. #define TRUE       -1
  72. #define FALSE        0
  73. #define SUCCESS     0
  74. #define O_RDONLY    0
  75. #define USER_ERR    0    /* Specified fileref must only be used
  76.                with -number command-line option */
  77. #define BAD_FREF    1    /* Illegal file reference */
  78. #define BAD_ARGS    2    /* Illegal command line */
  79. #define BAD_OPT     3    /* Illegal option */
  80. #define BAD_USER    4    /* Illegal user number */
  81. #define BAD_DRV     5    /* Illegal drive names */
  82. #define SAME_DRV    6    /* Same drive name for output as input */
  83. #define OPN_ERR     8    /* File open error */
  84. #define READ_ERR    9    /* File read error */
  85. #define CLS_ERR    10    /* File close error */
  86. #define BAD_VFY    11    /* File verify error */
  87. #define DIR_IO        6    /* BDOS Direct I/O service */
  88. #define RESET_DRV  13    /* BDOS Reset All Drives service */
  89. #define SEL_DRV       14    /* BDOS Select Drive service */
  90. #define SRCH_F       17    /* BDOS Search Next service */
  91. #define SRCH_N       18    /* BDOS Search Next service */
  92. #define GET_DRV       25    /* BDOS Get Default Drive service */
  93. #define SET_DMA       26    /* BDOS Set DMA Address service */
  94. #define SET_ATT       30    /* BDOS Set File Attributes service */
  95. #define USER_CODE  32    /* BDOS Get/Set User Code service */
  96. #define MAX_USER   32    /* 32 user codes under CP/M (see DR's
  97.                documentation for BDOS Service 32) */
  98.  
  99. /*** GLOBAL VARIABLES ***/
  100.  
  101. char ent_drv,    /* Entry drive code */
  102.      ent_user,    /* Entry user code */
  103.      cur_user;    /* Current user code */
  104.  
  105. /*** MAIN BODY OF CODE ***/
  106.  
  107. main(argc,argv)
  108. int argc;
  109. char *argv[];
  110. {
  111.   char in_dsk,        /* Drive name of input disk */
  112.        out_dsk,        /* Drive name of output (backup) disk */
  113.        in_drv,        /* Drive code of input disk */
  114.        out_drv,        /* Drive code of output disk */
  115.        seg_no,        /* Segment number for split files */
  116.        in_file[15],    /* Fileref of current input file */
  117.        out_file[15],    /* Fileref of current output file */
  118.        c,        /* Scratch variable */
  119.        *s,        /* Scratch string pointer */
  120.        *buffer,        /* Pointer to directory entry returned */
  121.             /* by "srch_file()" */
  122.        *srch_file(),
  123.        *malloc();
  124.  
  125.   /* File control blocks of current input and output files */
  126.  
  127.   static char in_fcb[33],    /* (Automatically initialized */
  128.           out_fcb[33];    /* to zero by compiler) */
  129.  
  130.   /* Structure for linked list of filerefs */
  131.  
  132.   struct file_ref
  133.   {
  134.     char name[12];        /* File reference */
  135.     struct file_ref *next;    /* Pointer to next instance */
  136.   } root,            /* Start of linked list */
  137.     *fref_1,            /* Scratch pointers to */
  138.     *fref_2;            /* linked list instances */
  139.  
  140.   /* Initialized file control block for "srch_file()". This FCB
  141.      is for a fully ambiguous fileref that causes "srch_file()"
  142.      to return all directory entries for the current default
  143.      drive. */
  144.  
  145.   static char fcb[] = {'?','?','?','?','?','?','?','?',
  146.                '?','?','?','?','?',0,0,0};
  147.  
  148.   int file_cnt = 0,    /* Count of file to be backed up */
  149.       dup_flag,        /* Duplicate fileref flag */
  150.       all_files,    /* All_files flag (cmd-line option) */
  151.       fast_copy,    /* Fast copy flag (cmd-line option) */
  152.       hard_disk,    /* Hard disk flag (cmd-line option) */
  153.       query,        /* Query flag (cmd-line option) */
  154.       system,        /* System flag (cmd-line option) */
  155.       user_no,        /* User number (cmd-line option) */
  156.       next_flag = FALSE;/* Flag to indicate to "srch_file()"
  157.                that a "search next" is required */
  158.  
  159.   register int i,j;    /* Loop indices */
  160.  
  161.   long begin,        /* Input file position variables */
  162.        end;
  163.  
  164.   /* Display program header */
  165.  
  166.   printf("\nBU Version 1.2");
  167.   printf("                                 Copyright 1985");
  168.   printf(" byHeart Software\n\n");
  169.  
  170.   /* Initialize command-line options */
  171.  
  172.   all_files = FALSE;    /* Copy only non-archived files */
  173.   fast_copy = FALSE;    /* Copy files with verification */
  174.   hard_disk = FALSE;    /* Files will not be split across backup
  175.                disks if remaining capacity of backup
  176.                disk is less than current file size */
  177.   query = FALSE;    /* Backup without query */
  178.   system = FALSE;    /* Assign directory attribute to all
  179.                backup files */
  180.   user_no = ALL;    /* Backup files in all user areas */  
  181.  
  182.   /* Parse command line for user-selected options (if any) */
  183.             
  184.   if(argc < 3)
  185.     error(BAD_ARGS,NULL);    /* Illegal command line */
  186.   if(argc > 3)
  187.   {
  188.     i = 3;  /* Start with third command-line argument */
  189.     while(i < argc)
  190.     {
  191.       if(*argv[i] != '-')
  192.     error(BAD_OPT,argv[i]);  /* Missing leading '-' */
  193.       s = argv[i]+1;
  194.       while(*s)
  195.       {
  196.     if(*s == 'A')        /* Check for all_files option */
  197.       all_files = TRUE;
  198.     else if(*s == 'F')  /* Check for fast copy option */
  199.       fast_copy = TRUE;
  200.     else if(*s == 'H')  /* Check for hard disk option */
  201.       hard_disk = TRUE;
  202.     else if(*s == 'Q')  /* Check for query option */
  203.       query = TRUE;
  204.     else if(*s == 'S')  /* Check for system option */
  205.       system = TRUE;
  206.     else if(isdigit(*s))  /* Check for user number option */
  207.     {
  208.       user_no = *s++ - '0';
  209.       if(isdigit(*s))
  210.         user_no = user_no * 10 + *s++ - '0';
  211.       if(user_no < 0 || user_no > 31)
  212.         error(BAD_USER,argv[i]);
  213.       continue;
  214.     }
  215.     else
  216.       error(BAD_OPT,argv[i]);
  217.     s++;
  218.       }
  219.     i++;
  220.     }
  221.   }
  222.  
  223.   /* Validate input parameters */
  224.  
  225.   if(*(argv[1]+1) != '\0')  /* Check for specified fileref */
  226.   {
  227.     if(user_no == ALL)         /* Can only use with specified */
  228.       error(USER_ERR,NULL);  /* user number (-n option) */
  229.  
  230.     /* Modify "fcb[]" to incorporate fileref */
  231.  
  232.     if(copy_fref(fcb,argv[1]) == ERROR)
  233.       error(BAD_FREF,argv[1]);
  234.   }
  235.   if(*argv[1] < 'A' || *argv[1] > 'P' ||
  236.       *argv[2] < 'A' || *argv[2] > 'P')
  237.     error(BAD_DRV,NULL);    /* Illegal drive names */
  238.   if(*argv[1] == *argv[2])
  239.     error(SAME_DRV,NULL);    /* Drive names are same